package convention;

import java.util.HashMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author wangzhengpeng
 */
public class Test {

    private static Thread threadA, threadB, threadC;
    public static final int count = 10;

    public static Lock lock = new ReentrantLock();
    public static Condition conditionA = lock.newCondition();
    public static Condition conditionB = lock.newCondition();
    public static Condition conditionC = lock.newCondition();
    int state = 0;

    private static Semaphore semaphoreA = new Semaphore(1);
    private static Semaphore semaphoreB = new Semaphore(0);
    private static Semaphore semaphoreC = new Semaphore(0);

    Object lockObject = new Object();
   HashMap hashMap = new HashMap();

    public static void main(String[] args) {
        // 使用Synchonized wait notify
//        Test test = new Test();
//        new Thread(() -> test.printLetterUsingWaitNotify(0), "A").start();
//        new Thread(() -> test.printLetterUsingWaitNotify(1), "B").start();
//        new Thread(() -> test.printLetterUsingWaitNotify(2), "C").start();

        //使用Semaphore
//        Test test = new Test();
//        new Thread(() -> test.printLetterUsingSemaphore(semaphoreA, semaphoreB), "A").start();
//        new Thread(() -> test.printLetterUsingSemaphore(semaphoreB, semaphoreC), "B").start();
//        new Thread(() -> test.printLetterUsingSemaphore(semaphoreC, semaphoreA), "C").start();

        // 使用LockCondition
//        Test test = new Test();
//        new Thread(() -> test.printLetter(0, conditionA, conditionB), "A").start();
//        new Thread(() -> test.printLetter(1, conditionB, conditionC), "B").start();
//        new Thread(() -> test.printLetter(2, conditionC, conditionA), "C").start();

//        //：使用Lock
//        Test test = new Test();
//        new Thread(() -> {
//            test.printLetter(0);
//        }, "A").start();
//        new Thread(() -> {
//            test.printLetter(1);
//        }, "B").start();
//        new Thread(() -> {
//            test.printLetter(2);
//        }, "C").start();

//        使用：LockSupport
//        threadA = new Thread(() -> {
//            for (int i = 0; i < count; i++) {
//                LockSupport.unpark(threadB);
//                System.out.print(Thread.currentThread().getName());
//                LockSupport.park();
//            }
//        }, "A");
//
//        threadB = new Thread(() -> {
//            for (int i = 0; i < count; i++) {
//                LockSupport.park();
//                System.out.print(Thread.currentThread().getName());
//                LockSupport.unpark(threadC);
//            }
//        }, "B");
//
//        threadC = new Thread(() -> {
//            for (int i = 0; i < count; i++) {
//                LockSupport.park();
//                System.out.print(Thread.currentThread().getName());
//                LockSupport.unpark(threadA);
//            }
//        }, "C");
//
//        threadA.start();
//        threadB.start();
//        threadC.start();
    }

//    private void printLetterUsingWaitNotify(int target) {
//        for (int i = 0; i < count; ) {
//            synchronized (lockObject) {
//                while (state % 3 != target) {
//                    try {
//                        lockObject.wait();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//                i++;
//                state++;
//                System.out.print(Thread.currentThread().getName());
//                lockObject.notifyAll();
//            }
//        }
//    }

//    private void printLetter(int target) {
//        for (int i = 0; i < count; ) {
//            lock.lock();
//            if (state % 3 == target) {
//                state++;
//                i++;
//                System.out.print(Thread.currentThread().getName());
//            }
//            lock.unlock();
//        }
//    }


//    private void printLetter(int target, Condition curr, Condition next) {
//        for (int i = 0; i < count; i++) {
//            try {
//                lock.lock();
//                while (state % 3 != target) {
//                    curr.await();
//                }
//                state++;
//                i++;
//                System.out.print(Thread.currentThread().getName());
//                next.signal();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }finally {
//                lock.unlock();
//            }
//        }
//    }

//    private void printLetterUsingSemaphore(Semaphore curr, Semaphore next) {
//        for (int i = 0; i < count; i++) {
//            try {
//                curr.acquire();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.print(Thread.currentThread().getName());
//            next.release();
//        }
//    }

}
